package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.album.TrackListVo;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private AlbumInfoService albumInfoService;

	@Autowired
	private TrackStatMapper trackStatMapper;
	/**
	 * 保存音频信息
	 *
	 * @param trackInfoVo 音频信息对象
	 * @param userId 用户ID
	 */
	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
		// 创建TrackInfo对象
		TrackInfo trackInfo = new TrackInfo();
		// 将trackInfoVo的属性复制到trackInfo对象中
		BeanUtils.copyProperties(trackInfoVo, trackInfo);
		// 设置用户ID
		trackInfo.setUserId(userId);
		// 设置来源为上传
		trackInfo.setSource(SystemConstant.TRACK_SOURCE_UPLOAD);
		// 设置状态为通过
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);

		// 获取流媒体信息.
		// 根据mediaFileId获取TrackMediaInfoVo对象
		TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfoById(trackInfoVo.getMediaFileId());
		// 设置媒体时长
		trackInfo.setMediaDuration(BigDecimal.valueOf(trackMediaInfoVo.getDuration()));
		// 设置媒体URL
		trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
		// 设置媒体类型
		trackInfo.setMediaType(trackMediaInfoVo.getType());
		// 设置媒体大小
		trackInfo.setMediaSize(trackMediaInfoVo.getSize());

		// 获取上一条声音
		// 查询相同albumId的最新一条TrackInfo记录
		TrackInfo preTrackInfo = this.getOne(new LambdaQueryWrapper<TrackInfo>()
												.eq(TrackInfo::getAlbumId, trackInfoVo.getAlbumId())
												.orderByDesc(TrackInfo::getId)
												.select(TrackInfo::getOrderNum)
												.last("limit 1"));
		// 初始化排序号
		int orderNum = 1;
		// 如果存在前一条记录，则排序号加1
		if (preTrackInfo != null) {
			orderNum = preTrackInfo.getOrderNum()+1;
		}
		// 设置排序号
		trackInfo.setOrderNum(orderNum);
		// 保存TrackInfo记录
		this.save(trackInfo);

		//更新专辑声音总数
		// 根据albumId获取AlbumInfo对象
		AlbumInfo albumInfoById = albumInfoService.getAlbumInfoById(trackInfoVo.getAlbumId());
		// 包含音频数加1
		albumInfoById.setIncludeTrackCount(albumInfoById.getIncludeTrackCount()+1);
		// 更新AlbumInfo记录
		albumInfoService.updateById(albumInfoById);

		// 初始化统计数据
		// 保存TrackStat记录，状态为收藏
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT);
		// 保存TrackStat记录，状态为播放
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		// 保存TrackStat记录，状态为评论
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT);
		// 保存TrackStat记录，状态为点赞
		saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE);

	}

	/**
	 * 重写findUserTrackPage方法，用于分页查询用户轨迹信息
	 *
	 * @param page 分页的页码
	 * @param limit 每页显示的数量
	 * @param trackInfoQuery 查询条件对象
	 * @return 返回分页查询结果，类型为IPage<TrackListVo>
	 */
	@Override
	// 重写findUserTrackPage方法，用于分页查询用户轨迹信息
	public IPage<TrackListVo> findUserTrackPage(Long page, Long limit, TrackInfoQuery trackInfoQuery) {
		// 创建分页对象，指定页码和每页显示数量
		Page<TrackListVo> trackListVoIPage = new Page<TrackListVo>(page, limit);
		// 调用Mapper层方法，传入分页对象和查询条件，返回分页结果
		return trackInfoMapper.findUserTrackPage(trackListVoIPage, trackInfoQuery);
	}

	@Override
	public void updateTrackInfo(TrackInfoVo trackInfoVo, Long id) {
		TrackInfo trackInfo = this.getById(id);
		String dbMediaFileId = trackInfo.getMediaFileId();
		String voMediaFileId = trackInfoVo.getMediaFileId();
		BeanUtils.copyProperties(trackInfoVo, trackInfo);

		if (!voMediaFileId.equals(dbMediaFileId)) {
			TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfoById(trackInfoVo.getMediaFileId());
			if (trackMediaInfoVo == null) {
				throw new GuiguException(ResultCodeEnum.VOD_FILE_ID_ERROR);
			}
			trackInfo.setMediaDuration(BigDecimal.valueOf(trackMediaInfoVo.getDuration()));
			trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
			trackInfo.setMediaType(trackMediaInfoVo.getType());
			trackInfo.setMediaSize(trackMediaInfoVo.getSize());
		}

		this.updateById(trackInfo);
	}

	@Override
	public void removeTrackInfo(Long id) {
		TrackInfo trackInfo = getById(id);
		this.removeById(id);

		AlbumInfo albumInfoById = albumInfoService.getAlbumInfoById(trackInfo.getAlbumId());
		albumInfoById.setIncludeTrackCount(albumInfoById.getIncludeTrackCount()-1);
		albumInfoService.updateById(albumInfoById);

		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, id));
		vodService.removeTrackMediaInfo(trackInfo.getMediaFileId());

	}


	/**
	 * 保存音频统计信息
	 *
	 * @param trackId 音频ID
	 * @param statType 统计类型
	 */
	private void saveTrackStat(Long trackId,String statType) {
		// 创建一个新的TrackStat对象
		TrackStat trackStat = new TrackStat();
		// 设置音频ID
		trackStat.setTrackId(trackId);
		// 设置统计类型
		trackStat.setStatType(statType);
		// 设置统计数量为0
		trackStat.setStatNum(0);
		// 将trackStat对象插入到数据库中
		trackStatMapper.insert(trackStat);
	}


}
